<template>
  <div class="app-container">
    <el-form :inline="true"
             :model="formInline"
             ref="queryForm"
             size="small"
             v-show="showSearch"
             class="demo-form-inline">

      <el-form-item label="角色名称">
        <el-input v-model="formInline.roleName" placeholder="请输入角色名称" clearable />
      </el-form-item>

      <el-form-item label="权限字符">
        <el-input v-model="formInline.roleKey" placeholder="请输入权限字符" clearable />
      </el-form-item>

      <el-form-item label="状态">
        <el-select v-model="formInline.status" placeholder="角色状态">
          <el-option label="正常" value="0" />
          <el-option label="停用" value="1" />
        </el-select>
      </el-form-item>

      <el-form-item label="创建时间" required>
        <span class="demonstration" />
        <el-date-picker
          v-model="value1"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        />
      </el-form-item>
      <br>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="onSubmit">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="reset">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
      </el-col>
      <!--      <el-col :span="1.5">-->
      <!--        <el-button type="success" plain icon="el-icon-edit" size="mini" @click="handleUpdate">修改</el-button>-->
      <!--      </el-col>-->
      <el-col :span="1.5">
        <el-button

          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
        >导出当前页</el-button>
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExportAll"

        >导出全部</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDeleteBatch"
        >删除
        </el-button>
      </el-col>
<!--      <el-col :span="1.5">-->
<!--        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>-->
<!--      </el-col>-->
      <!--隐藏搜索+刷新-->
      <right-toolbar
        :show-search.sync="showSearch"
        @queryTable="onSubmit"
      />
    </el-row>

    <!-- 新增对话框 开始   -->
    <el-dialog title="添加角色" :visible.sync="dialogFormVisible">
      <el-form ref="form" :model="form" :rules="rules">

        <el-form-item label="角色名称" :label-width="formLabelWidth" prop="roleName">
          <el-input v-model="form.roleName" maxlength="15" show-word-limit placeholder="请输入角色名称" />
        </el-form-item>

        <el-form-item label="权限字符" :label-width="formLabelWidth" prop="roleKey">
          <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
        </el-form-item>

        <el-form-item label="角色顺序" :label-width="formLabelWidth">
          <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
        </el-form-item>

        <el-form-item label="状态" >
          <el-radio-group v-model="form.status"  >
            <el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">
              {{ dict.dictLabel }}
            </el-radio>
          </el-radio-group>
        </el-form-item>


        <!--                        // 多选的按钮-->
        <el-form-item label="菜单权限">
          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动
          </el-checkbox>
          <el-tree
            ref="menu"
            class="tree-border"
            :data="menuOptions"
            show-checkbox
            node-key="menuId"
            :check-strictly="!form.menuCheckStrictly"
            empty-text="加载中，请稍后"
            :props="defaultProps">
          </el-tree>
        </el-form-item>
        <el-form-item label="备注" :label-width="formLabelWidth">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveForm()">确 定</el-button>
      </div>
    </el-dialog>
    <!--对话框 end-->

    <!--表格数据 开始-->
    <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange" stripe border>
      <el-table-column type="selection" width="55" align="center" :selectable="selectHandle"/>
      <el-table-column label="角色编号" prop="roleId" width="120"/>
      <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150"/>
      <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150"/>
      <el-table-column label="显示顺序" prop="roleSort" width="80"  align="center"/>

      <el-table-column label="状态"  width="70" align="center">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.status"
            active-value="0"
            inactive-value="1"
            @change="handleStatusChange(scope.row)"
          ></el-switch>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" align="center" prop="createTime">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="修改时间" align="center" prop="updateTime">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.updateTime) }}</span>
        </template>
      </el-table-column>



      <el-table-column label="操作" align="center" class-name="small-padding " width="200px">
        <template slot-scope="scope" v-if="scope.row.roleId !== 1">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDeleteOne(scope.row)">删除</el-button>

          <el-dropdown trigger="click" size="mini">
            <el-button size="mini" type="text" icon="el-icon-d-arrow-right el-icon--right"
              @click.native="more">更多
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item icon="el-icon-plus" @click.native="dataPermission(scope.row)">数据权限</el-dropdown-item>
              <el-dropdown-item icon="el-icon-circle-plus" @click.native="AssignUsers(scope.row)" >分配用户</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>

        </template>
      </el-table-column>
    </el-table>
    <!--表格   结束-->

    <!-- 分配数据权限 开始   -->
    <el-dialog title="分配数据权限" :visible.sync="dataPermissionDialogForm">
      <el-form :model="formData" >

        <el-form-item label="角色名称" :label-width="formLabelWidth" prop="roleName">
          <el-input disabled v-model="formData.roleName" maxlength="15" show-word-limit placeholder="请输入角色名称" />
        </el-form-item>

        <el-form-item label="权限字符" :label-width="formLabelWidth" prop="roleKey">
          <el-input disabled v-model="formData.roleKey" placeholder="请输入权限字符" />
        </el-form-item>

        <el-form-item label="权限范围" :label-width="formLabelWidth">
<!--          <template>-->
<!--            <el-select v-model="value" placeholder="请选择" @change="powChange">-->
<!--              <el-option-->
<!--                v-for="item in options"-->
<!--                :key="item.value"-->
<!--                :label="item.label"-->
<!--                :value="item.value">-->
<!--              </el-option>-->
<!--            </el-select>-->
<!--          </template>-->

          <el-tree
            ref="dept"
            class="tree-border"
            :data="powOptions"
            show-checkbox
            node-key="deptId"
            empty-text="加载中，请稍后"
            :check-strictly="checkStrictly"
            :default-expand-all="true"
            :props="powOptionsProps">
          </el-tree>
        </el-form-item>




<!--        <el-form-item label="数据权限">-->
<!--          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>-->
<!--          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>-->
<!--          <el-checkbox v-model="formData.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>-->


<!--        </el-form-item>-->

      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dataPermissionDialogForm = false">取 消</el-button>
        <el-button type="primary" @click="savePowForm()">确 定</el-button>
      </div>
    </el-dialog>



    <!--分页 开始-->
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="current"
      :page-sizes="[2,5, 10, 20, 40]"
      :page-size="size"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total">
    </el-pagination>
    <!--分页 结束-->
  </div>
</template>

<script>
  import {parseTime} from "../../../utils";
  import store from "../../../store";
  import {getToken} from "../../../utils/auth";

  var userName = store.getters.name;
  export default {
    name: "index",
    data() {
      return {
        title: "",
        // 表单校验
        rules: {
          roleName: [
            {required: true, message: "角色名称不能为空", trigger: "blur"}
          ],
          roleKey: [
            {required: true, message: "权限字符不能为空", trigger: "blur"}
          ],
          roleSort: [
            {required: true, message: "角色顺序不能为空", trigger: "blur"}
          ]
        },
        // 菜单列表  绑定el-tree 的data
        menuOptions: [],

        menuExpand: false,
        menuNodeAll: false,

        props: {                //??????
          label: 'name',
          children: 'zones'
        },

        defaultProps: {
          children: "menus",  //对应着后后台集合里的子集合 属性名称
          label: "menuName"
        },
        textarea: '',
        menuCheckStrictly: true,

        dialogFormVisible: false,   // 添加/修改框默认关闭
        form: {
          menuIds: [],
        },        //添加数据
        menuIds: [],
        formLabelWidth: '120px',


        statusOptions: [],   //角色状态

        single: true,        // 非单个禁用
        multiple: true,      // 非多个禁用
        ids: [],             //选中数组
        //-------------------

        deptIds: [],
        dataPermissionDialogForm:false,

        checkStrictly :false,
        //分配权限对话框
        formData:{
          deptIds: [],
        },

        options: [{
          value: '选项1',
          label: '自定义数据类型'
        }, {
          value: '选项2',
          label: '全部数据类型'
        }],

        value: '',
        powChang:false,

        // 权限菜单列表  绑定el-tree 的data
        powOptions: [],


        powOptionsProps: {
          children: "depts",  //对应着后后台集合里的子集合 属性名称
          label: "deptName"
        },

        //----------------------------------------------------
        showSearch: true,
        loading: false,      // 遮罩层

        roleList: [],         //角色数据
        current: 1,          //当前页数
        size: 2,             //当前条数
        total: 0,             //总条数
        value1: '',           //时间
        role: {},             //模糊查询表单数据
        formInline: {         //条件查询
          roleName: '',
          roleKey: '',
          status: '',
          startTime: '',
          endTime: ''
        },
      }
    },

    methods: {
      //新增按钮
      handleAdd() {
        this.reset2();
        this.title = "添加角色";
        this.dialogFormVisible = true;
        this.$nextTick(function () {      //Cannot read property 'setCheckedKeys' of undefined",,因为this.dialogVisible = true时并没有立即更新dom，而是等整个逻辑执行完后再一次新渲染，因此此时的弹框并未渲染，在dom树中是不存在的，
          // this.$refs.tree is undefined的所以setCheckedKeys肯定也是undefined。
          this.$refs.menu.setCheckedKeys([])
        })
      },
      // 表单重置
      reset2() {
        if (this.$refs.menu != undefined) {
          this.$refs.menu.setCheckedKeys([]);
        }
        this.menuExpand = false;
        this.menuNodeAll = false;
        this.deptExpand = true;
        this.deptNodeAll = false;
        this.form = {
          roleId: "",
          roleName: "",
          roleKey: "",
          roleSort: 1,
          status: '0',
          menuIds: [],
          deptIds: [],
          menuCheckStrictly: 1,
          remark: ""
          // createBy: userName
        };
      },

      //加载页面数据
      loadRolesList(current) {

        this.loading = true;
        /*获取当前用户名*/
        // console.log(userName)
        //分页数据
        this.axios.get("/sysRole/list/",
          {
            params: {
              current: current,
              size: this.size,
              roleName: this.formInline.roleName,
              roleKey: this.formInline.roleKey,
              status: this.formInline.status,
              startTime: this.formInline.startTime,
              endTime: this.formInline.endTime,
              //------------------------------
              userName: userName
            }
          }).then(result => {
          //处理后台数据(将后台result.data数据与roleList集合绑定)
          this.roleList = result.data.data.records;
          this.total = result.data.data.total;
        });
        // //查询 角色状态
        this.axios.get("/sysRole/status").then(res => {
          this.statusOptions = res.data.data;
        });

        //新增 菜单树 数据
        this.axios.get("/sysMenu/menu/", {
          params: {
            menuName: "",
            status: "",
          }
        }).then(res => {
          this.menuOptions = res.data.data;
        });

        // 数据 权限 树 结构展示
        this.axios({
          url:"/sysDept/dept/",
          params:{
            deptName:"",
            status:"",
          }
        }).then(res=>{
          this.powOptions = res.data.data;
        });

        this.loading = false;
      },

      //添加/修改 提交按钮
      async saveForm() {
        if (this.title === "添加角色") {

          this.form.createBy = userName;                                   //创建者
          this.form.menuIds = this.$refs.menu.getCheckedKeys();                      //将数据添加到的对话表单框 from 对象中  返回目前被选中的节点的 key 所组成的数组
          this.menuOptions = this.getMenuAllCheckedKeys();          //调用  获取所有菜单节点数据方法

          console.log(this.form);
          //  添加
          await this.axios({
            url: "/sysRole/add",
            method: "post",
            data: this.form
          }).then(res => {

            if (res.data.data === "ok") {
              this.$message.success("添加成功");
            } else {
              this.$message.error("添加失败");
            }

          })
        } else if (this.title === "修改角色") {
          console.log("修改角色");
          this.form.menuIds = this.$refs.menu.getCheckedKeys();
          this.menuOptions = this.getMenuAllCheckedKeys();

          //  修改
          await this.axios({
            url: "/sysRole/update",
            method: "post",
            data: this.form
          }).then(res => {
            if (res.data.data === "ok") {
              this.$message.success('修改成功');
            } else {
              this.$message.error("修改失败");
            }
          })
        }
        this.loadRolesList(this.current);
        this.dialogFormVisible = false;
      },

      //点击弹出修改框
      async handleUpdate(row) {
        if (row.status !== '0') {
          this.$message.error('当前角色已被停用！无法进行修改操作！');
        } else {
          this.title = "修改角色";
          this.dialogFormVisible = true;
          this.form = row;
          console.log(this.form)
          await this.axios.get("/sysRoleMenu/getMenuIdsByRoldId", {
            params: {
              roleId: this.form.roleId
            }
          }).then(res => {
            this.menuIds = [];                                     //   置空

            for (let i = 0; i < res.data.data.length; i++) {     //遍历添加
              this.menuIds.push(res.data.data[i].menuId)
            }
            this.$nextTick(() => {
              this.$refs.menu.setCheckedKeys(this.menuIds)
            })
          })
        }
      },

      // 树权限（展开/折叠）
      handleCheckedTreeExpand(value, type) {
        if (type == 'menu') {
          let treeList = this.menuOptions;
          for (let i = 0; i < treeList.length; i++) {
            this.$refs.menu.store.nodesMap[treeList[i].menuId].expanded = value;
          }

        } else if (type == 'dept') {
          // let treeList = this.deptOptions;
          // for (let i = 0; i < treeList.length; i++) {
          //   this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
          // }
        }
      },
      // 树权限（全选/全不选）
      handleCheckedTreeNodeAll(value, type) {
        if (type == 'menu') {
          this.$refs.menu.setCheckedNodes(value ? this.menuOptions : []);
        } else if (type == 'dept') {
          // this.$refs.dept.setCheckedNodes(value ? this.deptOptions : []);
        }
      },
      // 树权限（父子联动）
      handleCheckedTreeConnect(value, type) {
        if (type == 'menu') {
          this.form.menuCheckStrictly = value ? true : false;
        } else if (type == 'dept') {
          // this.form.deptCheckStrictly = value ? true : false;
        }
      },
      // 所有菜单节点数据
      getMenuAllCheckedKeys() {

        // 目前被选中的菜单节点
        let checkedKeys = this.$refs.menu.getCheckedKeys();         //返回目前被选中的节点的 key 所组成的数组
        console.log("目前被选中的菜单节点 所有");
        console.log(checkedKeys);

        // 被选中的菜单节点
        let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();             //返回半选中的节点的 key 所组成的数组
        checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);    //unshift() 方法将一个或多个元素添加到数组的开头，并返回新数组的长度
        console.log("被半选中的菜单节点")
        console.log(halfCheckedKeys)

        console.log("合并后")
        console.log(checkedKeys)

        return checkedKeys;                                         //返回  合并后 []  为什么合并？？？？？？？ 因为只选 子节点 只会返回子节点的id ,所有还需要父节点的id
      },

      //单删除
      async handleDeleteOne(row) {
        this.$confirm('是否删除角色编号为"' + row.roleId + '"的数据项？', "警告", {
          confirmButtonClass: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(async () => {
            await this.axios({
              url: "sysRole/delete",
              method: "delete",
              params: {
                roleId: row.roleId
              }
            }).then(res => {
              if (res.data.data == "ok") {
                this.$message.success('删除成功');
              } else {
                this.$message.error("删除失败");
              }

              const totalPage = Math.ceil((this.total - 1) / this.size); // 总页数
              this.current = this.current > totalPage ? totalPage : this.current;
              this.current = this.current < 1 ? 1 : this.current;

              this.loadRolesList(this.current)
            })
          }
        )
      },
      //批量删除
      async handleDeleteBatch() {

        await this.axios({
          url: "sysRole/BatchDelete",
          method: "delete",
          data: this.ids
        }).then(res => {
          if (res.data.data == "ok") {
            this.$message.success("删除成功")
          } else {
            this.$message.error("删除失败")
          }
        })
      },
      // 多选框选中数据
      handleSelectionChange(selection) {
        this.ids = selection.map(item => item.roleId)
        this.single = selection.length != 1
        this.multiple = !selection.length
      },

      // 角色状态修改
      async handleStatusChange(row) {
        // console.log(row)
        let text = row.status == "0" ? "启用" : "停用";
        this.$confirm('是否' + text + '角色编号为"' + row.roleId + '"的数据项？', "注意", {
          confirmButtonClass: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(async () => {
          await this.axios.put("sysRole/updateRoleStatus", row).then(res => {
            if (res.data.data === "ok") {
              this.$message.success(text + "成功")
            }
          })
        })
      },

      // 多选中禁用一行
      selectHandle(row) {
        return !(row.roleKey==="admin");
      },

      //-------------------------------------------------------------------------------------------------------
      //点击更多
      more(){
        this.value="";
        if (this.$refs.dept != undefined) {
          this.$refs.dept.setCheckedKeys([]);
        }
        this.formData = {
          status: '0',
          deptIds: [],
        };
      },
      //切换权限
      // powChange(){
      //   this.powChang = this.value === '选项1';
      //     this.dataPermission(this.formData);
      // },

      //数据权限
      dataPermission(row){

        if (row.status !== '0') {
          this.$message.error('当前角色已被停用！无法进行修改操作！');
        }else {
        //行数数据
        this.formData=row;

        //对话框
        this.dataPermissionDialogForm=true;

        // 该角色 有的权限数据
        this.axios({
          url:"/sysDept/RoleId/",
          params:{
          roleId:this.formData.roleId
          }
        }).then(res=>{
          this.deptIds = [];                                    //   置空
          for (let i = 0; i < res.data.data.length; i++) {     //遍历添加
            this.deptIds.push(res.data.data[i].deptId)
          }
      this.checkStrictly = true;

      this.$nextTick(() => {
        this.$refs.dept.setCheckedKeys(this.deptIds);
        this.checkStrictly = false
      });
        })
        }

      },

      //保存权限  就是修改角色权限sys_role_dept
      savePowForm(){
        console.log("保存权限")

        let checkedKeys =   this.$refs.dept.getCheckedKeys(); //所有 打勾 节点

        var halfCheckedNodes = this.$refs.dept.getHalfCheckedKeys();//半选状态 就是 - 状态

        checkedKeys.unshift.apply(checkedKeys, halfCheckedNodes);

        this.formData.deptIds= checkedKeys;


        this.axios({
          url:"/sysRole/pow",
          method:"put",
          data:this.formData
        }).then(res=>{
          if (res.data.data === "ok") {
            this.$message.success('修改成功');
          } else {
            this.$message.error("修改失败");
          }
        })

        this.dataPermissionDialogForm=false;
        this.loadRolesList(this.current);
      },



      //-----------------------------------------------

      //模糊查询提交按钮
      onSubmit() {
        this.loading = true;
        //将日期转换为字符串
        if (this.value1[0] != null) {
          this.formInline.startTime = parseTime(this.value1[0]).slice(0, 10);
          this.formInline.endTime = parseTime(this.value1[1]).slice(0, 10);
        }

        this.loadRolesList(this.current)
        this.value1 = ''

      },
      //重置按钮
      reset() {
        this.formInline = {
          roleName: '',
          roleKey: '',
          status: ''
        },
          this.value1 = ''
      },

      handleSizeChange(val) {
        console.log(`每页 ${val} 条`);
        this.size = val;
        this.loadRolesList(this.current)
      },
      handleCurrentChange(val) {
        console.log(`当前页: ${val}`);
        this.current = val;
        this.loadRolesList(this.current)
      },

      //导出当前页数据
      handleExport(){
        window.open("http://localhost:8080/sysRole/export?current="+this.current+"&size="+this.size+"&roleName="
          +this.formInline.roleName+"&roleKey="+this.formInline.roleKey+"&status="+this.formInline.status
          +"&startTime="+this.formInline.startTime+"&endTime="+this.formInline.endTime+"&userName="+userName+"&Authorization="+getToken())
      },
      //导出所有数据
      handleExportAll(){
        console.log("导出所有数据")
        window.open("http://localhost:8080/sysRole/export?current="+1+"&size="+this.total+"&roleName="
          +this.formInline.roleName+"&roleKey="+this.formInline.roleKey+"&status="+this.formInline.status
          +"&startTime="+this.formInline.startTime+"&endTime="+this.formInline.endTime+"&userName="+userName+"&Authorization="+getToken())

      },

      /*格式化时间*/
      parseTime(time) {
        var date = new Date(time);
        return parseTime(date)
      }

    },
    created() {
      this.loadRolesList(this.current)
    }


  }

</script>

<style scoped>
  .tree-line {
    background: transparent;
    color: #81b0ff;
    font-size: 14px;
    line-height: 20px;
    margin-bottom: 15px;
  }
</style>
